// ==================================
// std::conditional
// ==================================

std::conditional 是 C++ 标准库中的一个模板元函数，定义在 <type_traits> 头文件中。它提供了一种在编译期根据条件选择类型的方法，类似于编程语言中的三元条件运算符 (condition ? type1 : type2)，但作用于类型而非值。

1. 基本语法
template <bool Condition, typename TrueType, typename FalseType>
struct conditional {
    using type = /* 根据Condition选择TrueType或FalseType */;
};

// C++14引入的辅助别名模板
template <bool Condition, typename TrueType, typename FalseType>
using conditional_t = typename conditional<Condition, TrueType, FalseType>::type;

2. 工作原理
如果 Condition 为 true，则 conditional<Condition, TrueType, FalseType>::type 是 TrueType
如果 Condition 为 false，则 conditional<Condition, TrueType, FalseType>::type 是 FalseType


3. 简单示例
#include <type_traits>
#include <iostream>

template <typename T>
void print_type_info() {
    // 根据类型是否为整数选择不同的类型
    using result_type = typename std::conditional<
        std::is_integral_v<T>,
        int,
        double
    >::type;
    
    std::cout << "For type " << typeid(T).name() 
              << ", result_type is " << typeid(result_type).name() 
              << std::endl;
}

int main() {
    print_type_info<int>();      // 选择int
    print_type_info<double>();   // 选择double
    print_type_info<char>();     // 选择int (因为char是整数类型)
    return 0;
}

4. 实际应用
// 1. 类型选择
// 根据大小选择最合适的整数类型
template <size_t Size>
struct select_int_type {
    using type = typename std::conditional<
        (Size <= 8),
        uint8_t,
        typename std::conditional<
            (Size <= 16),
            uint16_t,
            typename std::conditional<
                (Size <= 32),
                uint32_t,
                uint64_t
            >::type
        >::type
    >::type;
};

// C++14简化版本
template <size_t Size>
using select_int_t = std::conditional_t<
    (Size <= 8), uint8_t,
    std::conditional_t<
        (Size <= 16), uint16_t,
        std::conditional_t<
            (Size <= 32), uint32_t,
            uint64_t
        >
    >
>;

// 2. 类型特性选择
// 为不同类型选择合适的序列化方法
template <typename T>
struct serializer {
    using impl_type = typename std::conditional<
        std::is_pod_v<T>,
        binary_serializer<T>,    // POD类型使用二进制序列化
        text_serializer<T>       // 非POD类型使用文本序列化
    >::type;
    
    static void serialize(std::ostream& os, const T& value) {
        impl_type::serialize(os, value);
    }
};

// 3. 与其他类型特性结合
// 根据类型是否可复制选择存储策略
template <typename T>
class Container {
private:
    using storage_type = typename std::conditional<
        std::is_copy_constructible_v<T>,
        std::vector<T>,          // 可复制类型直接存储
        std::vector<std::unique_ptr<T>>  // 不可复制类型存储指针
    >::type;
    
    storage_type data;
    
public:
    // 容器实现...
};

// 4. 编译期算法中的条件逻辑
// 编译期计算最大公约数
template <unsigned A, unsigned B>
struct gcd {
    static constexpr unsigned value = 
        std::conditional_t<
            (A % B == 0)
            std::integral_constant<unsigned, B>,
            gcd<B, A % B>
        >::value;
};

template <unsigned A>
struct gcd<A, 0> {
    static constexpr unsigned value = A;
};